package com.itheima.util;


import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;

/**
 * @author stay foolish
 * @description 行至水穷处, 坐看云起时
 * @date 2022/11/22 21:04:29
 * @description 来源-
 * 注意:本代码参考9组组长郑世权靓仔.
 * 注意:本代码参考9组组长郑世权靓仔.
 * 注意:本代码参考9组组长郑世权靓仔.
 * 注意:本代码参考9组组长郑世权靓仔.
 * 注意:本代码参考9组组长郑世权靓仔.
 * 注意:本代码参考9组组长郑世权靓仔.
 */
public class SpringApplicationContext {
    // 1.创建map集合模拟Spring的IOC容器.
    private static HashMap<String, Object> map = new HashMap<>();
    /**
     * 2.构造方法传递需要解析的配置文件名称
     */
    public SpringApplicationContext(String xmlName) throws Exception {
        //调用方法解析配置文件
        map = parseXmlAndCreateIocContainer(xmlName);
    }
    // 3.提供方法解析beans.xml文件,然后创建对象存入map集合中
    public static HashMap<String, Object> parseXmlAndCreateIocContainer(String xmlName) throws Exception {
        // 获取字节输入流关联resoures文件下的xml文件
        InputStream is = SpringApplicationContext.class.getClassLoader().getResourceAsStream(xmlName);
        // 创建dom4j的专有对象关联字节输入流
        SAXReader reader = new SAXReader();
        // 获取整个document对象
        Document document = reader.read(is);
        // 获取根标签对象,这里是beans标签
        Element beans = document.getRootElement();
        Element bean = beans.element("bean");
        // 获取全类名
        String className = bean.attributeValue("class");
        String id = bean.attributeValue("id");
        // 根据传入的id获取集合的实例对象
        Object obj = map.get(id);
        // 判断集合中是否有实例对象
        if (obj == null) {
            // 没有就创建

            Class<?> clazz = Class.forName(className);
            obj = clazz.newInstance();
            // 将对象存入集合
            map.put(id, obj);
            // 获取所有property标签对象
            List<Element> list = bean.elements("property");
            for (Element property : list) {
                String username = property.attributeValue("name");
                String value = property.attributeValue("value");
                // username->UserName u->U
                char ch = Character.toUpperCase(username.charAt(0));
                // 先截取再拼接 username->sername,从1索引截到末尾
                username = username.substring(1);
                // setUsername
                String methodName = "set" + ch + username;
                // 依赖注入
                // 反射创建setUsername方法
                Method method = clazz.getMethod(methodName, String.class);
                // 执行方法
                method.invoke(obj, value);

            }
        }
        // 返回对象给调用者
        return map;

    }

    /**
     * 根据beanId获取对象
     *
     * @param beanId
     * @return
     */
    public Object getBean(String beanId) {
        Object obj = map.get(beanId);
        return obj;
    }


}

